package com.changgou.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.goods.feign.SkuFeign;
import com.changgou.goods.pojo.Sku;
import com.changgou.search.dao.SkuEsMapping;
import com.changgou.search.pojo.SkuInfo;
import com.changgou.search.service.SkuService;
import com.changgou.search.utils.SearchResultMapperImpl;
import entity.Result;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SkuServiceImpl implements SkuService {

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private SkuEsMapping skuEsMapping;

    /**
     * ElasticsearchTempalte :
     *可以实现索 引库的增删改查[高级搜索 ]
     */
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;




    /**
     * 多条件搜索（代码优化后最终结果）
     * @param searchMap
     * @return
     */
    @Override
    public Map<String,Object> search(Map<String, String> searchMap){
        //1.获取关键字的值
        String keywords = searchMap.get("keywords");

        if (StringUtils.isEmpty(keywords)) {
            keywords = "华为";//赋值给一个默认的值
        }
        //2.创建查询对象 的构建对象
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        //3.设置查询的条件

        //设置分组条件  商品分类
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuCategorygroup").field("categoryName").size(50));

        //设置分组条件  商品品牌
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuBrandgroup").field("brandName").size(50));

        //设置分组条件  商品的规格
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuSpecgroup").field("spec.keyword").size(10000));


        //设置高亮条件
        nativeSearchQueryBuilder.withHighlightFields(new HighlightBuilder.Field("name"));
        nativeSearchQueryBuilder.withHighlightBuilder(new HighlightBuilder().preTags("<em style=\"color:red\">").postTags("</em>"));

        //设置主关键字查询
        nativeSearchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery(keywords,"name","brandName","categoryName"));


        //多条件查询构建条件参数
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();


        if (!StringUtils.isEmpty(searchMap.get("brand"))) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("brandName", searchMap.get("brand")));
        }

        if (!StringUtils.isEmpty(searchMap.get("category"))) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("categoryName", searchMap.get("category")));
        }

        //规格过滤查询
        if (searchMap != null) {
            for (String key : searchMap.keySet()) {
                if (key.startsWith("spec_")) {
                    //特殊字符处理
                    String value = searchMap.get (key).replace( "//","");
                    boolQueryBuilder.filter(QueryBuilders.termQuery("specMap." + key.substring(5) + ".keyword", value));
                }
            }
        }

        //价格过滤查询
        /*String price = searchMap.get("price");
        if (!StringUtils.isEmpty(price)) {
            String[] split = price.split("-");
            if (!split[1].equalsIgnoreCase("*")) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").from(split[0], true).to(split[1], true));
            } else {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(split[0]));
            }
        }*/

        String price = searchMap.get("price");
        if (!StringUtils.isEmpty(price)){
            //price 0-500元 500-1000元 1000-1500元  1500-2000元 2000-3000元 3000元以上
            //去掉中文元和以上0-500 500- 1000 1000-1500 1500-2000 2000-3000 3000
            price = price.replace("元", "").replace("以上", "");
            //prices[]根据-分割 [0, 500] [500, 1000] ... [3000]
            String[] prices = price.split("-");
            if (prices!=null&&prices.length>0){
                //x一定不为空，y有可能为null
                //prices[O]!=null price>prices[0] price<=prices[1]
                boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gt(Integer.parseInt(prices[0])));
                if (prices.length==2){
                    boolQueryBuilder.must(QueryBuilders.rangeQuery("price").lte(Integer.parseInt(prices[1])));
                }
            }
            /*if (!prices[1].equalsIgnoreCase("*")) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").from(prices[0], true).to(prices[1], true));
            } else {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(prices[0]));
            }*/

        }



        //构建过滤查询
        nativeSearchQueryBuilder.withFilter(boolQueryBuilder);

        //构建分页查询
        Integer pageNum = 1;
        if (!StringUtils.isEmpty(searchMap.get("pageNum"))) {
            try {
                pageNum = Integer.valueOf(searchMap.get("pageNum"));
            } catch (NumberFormatException e) {
                e.printStackTrace();
                pageNum=1;
            }
        }
        Integer pageSize = 10;
        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNum - 1, pageSize));


        //构建排序查询
        String sortRule = searchMap.get("sortRule");
        String sortField = searchMap.get("sortField");
        if (!StringUtils.isEmpty(sortRule) && !StringUtils.isEmpty(sortField)) {
            //这里就不用valueOf(sortRule)了，容易出bug
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(sortRule.equals("DESC") ? SortOrder.DESC : SortOrder.ASC));
        }


        //4.构建查询对象
        NativeSearchQuery query = nativeSearchQueryBuilder.build();

        //5.执行查询
        AggregatedPage<SkuInfo> skuPage = elasticsearchTemplate.queryForPage(query, SkuInfo.class,new SearchResultMapperImpl());

        //获取分组结果  商品分类
        StringTerms stringTermsCategory = (StringTerms) skuPage.getAggregation("skuCategorygroup");
        //获取分组结果  商品品牌
        StringTerms stringTermsBrand = (StringTerms) skuPage.getAggregation("skuBrandgroup");
        //获取分组结果  商品规格数据
        StringTerms stringTermsSpec = (StringTerms) skuPage.getAggregation("skuSpecgroup");

        List<String> categoryList = getStringsCategoryList(stringTermsCategory);

        List<String> brandList = getStringsBrandList(stringTermsBrand);

        Map<String, Set<String>> specMap = putAllSpec(stringTermsSpec);


        //6.返回结果
        Map resultMap = new HashMap<>();

        resultMap.put("specMap", specMap);
        resultMap.put("categoryList", categoryList);
        resultMap.put("brandList", brandList);
        resultMap.put("rows", skuPage.getContent());
        resultMap.put("total", skuPage.getTotalElements());
        resultMap.put("totalPages", skuPage.getTotalPages());
        resultMap.put("pageNum", pageNum);
        resultMap.put("pageSize", pageSize);

        return resultMap;

    }

    /**
     * 获取品牌列表（优化后）
     *
     * @param stringTermsBrand
     * @return
     */
    private List<String> getStringsBrandList(StringTerms stringTermsBrand) {
        List<String> brandList = new ArrayList<>();
        if (stringTermsBrand != null) {
            for (StringTerms.Bucket bucket : stringTermsBrand.getBuckets()) {
                brandList.add(bucket.getKeyAsString());
            }
        }
        return brandList;
    }

    /**
     * 获取分类列表数据（优化后）
     *
     * @param stringTerms
     * @return
     */
    private List<String> getStringsCategoryList(StringTerms stringTerms) {
        List<String> categoryList = new ArrayList<>();
        if (stringTerms != null) {
            for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
                String keyAsString = bucket.getKeyAsString();//分组的值
                categoryList.add(keyAsString);
            }
        }
        return categoryList;
    }


    /**
     * 获取规格列表数据(优化后)
     *
     * @param stringTermsSpec
     * @return
     */
    private Map<String, Set<String>> putAllSpec(StringTerms stringTermsSpec) {
        Map<String, Set<String>> specMap = new HashMap<String, Set<String>>();

        Set<String> specList = new HashSet<>();

        if (stringTermsSpec != null) {
            for (StringTerms.Bucket bucket : stringTermsSpec.getBuckets()) {
                specList.add(bucket.getKeyAsString());
            }
        }

        for (String specjson : specList) {
            Map<String, String> map = JSON.parseObject(specjson, Map.class);
            for (Map.Entry<String, String> entry : map.entrySet()) {//
                String key = entry.getKey();        //规格名字
                String value = entry.getValue();    //规格选项值
                //获取当前规格名字对应的规格数据
                Set<String> specValues = specMap.get(key);
                if (specValues == null) {
                    specValues = new HashSet<String>();
                }
                //将当前规格加入到集合中
                specValues.add(value);
                //将数据存入到specMap中
                specMap.put(key, specValues);
            }
        }
        return specMap;
    }


    /**
     * 获取规格参数列表
     * @param stringTerms
     * @return
     */
    public List getGroupList(StringTerms stringTerms){
        List<String> list = new ArrayList();
        for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
            String brandName = bucket.getKeyAsString(); //其中的一个分类名字
            list.add(brandName);
        }
        return list;
    }


    /**
     * 多条件搜索
     * @param searchMap
     * @return
     */
    public Map<String,Object> search1(Map<String, String> searchMap){

        //搜索条件封装
        NativeSearchQueryBuilder nativeSearchQueryBuilder = builderBaseQuery(searchMap);

        //集合搜索
        Map<String, Object> map = searchList(nativeSearchQueryBuilder);

        //当用户选择了分类，将分类作为搜索条件，则不需要对分类进行分组搜索，因为分组搜索的数据是用于显示分类搜索条件的
        //分组查询分类集合
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuCategory").field("categoryName"));
        if (searchMap == null||StringUtils.isEmpty(searchMap.get("category"))){
            List<String> catogryList = searchCatogryList(nativeSearchQueryBuilder);
            map.put("categoryList",catogryList);
        }


        //当用户选择了品牌，将品牌作为搜索条件，则不需要对品牌进行分组搜索，因为分组搜索的数据是用于显示品牌搜索条件的
        //分组查询品牌集合
        if (searchMap == null||StringUtils.isEmpty(searchMap.get("brand"))){
            List<String> brandList = searchBrandList(nativeSearchQueryBuilder);
            map.put("brandList",brandList);
        }


        //当用户选择了规格，将规格作为搜索条件，则不需要对规格进行规格搜索，因为分组搜索的数据是用于显示规格搜索条件的
        //规格汇总合并查询
        HashMap<String, Set<String>> searchSpcList = putAllSpec(nativeSearchQueryBuilder);
        map.put("searchSpcList",searchSpcList);

        return map;

    }

    /**
     * 搜索条件封装
     * @param searchMap
     * @return
     */
    private NativeSearchQueryBuilder builderBaseQuery(Map<String, String> searchMap) {
        //NativeSearchQueryBuilder 搜索条件构建对象，用于封装各种搜索条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        //BoolQuery  must,must_not,should  组合查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //构建搜索条件
        if (searchMap != null && searchMap.size() > 0){
            //根据关键词搜索
            String keywords = searchMap.get("keywords");
            //如果关键词为空则搜索关键词
            if (!StringUtils.isEmpty(keywords)){
                //field里填查询的域
                //nativeSearchQueryBuilder.withQuery(QueryBuilders.queryStringQuery(keywords).field("name"));
                boolQuery.must(QueryBuilders.queryStringQuery(keywords).field("name"));
            }
            //输入了分类
            String category = searchMap.get("category");
            if (!StringUtils.isEmpty(category)){
                boolQuery.must(QueryBuilders.termQuery("categoryName",category));
            }
            //输入了品牌
            String brand = searchMap.get("brand");
            if (!StringUtils.isEmpty(brand)){
                boolQuery.must(QueryBuilders.termQuery("brandName",brand));
            }

            //规格过滤实现: spec_ _网络=联通3G&spec_ 颜色=红
            for (Map.Entry<String, String> entry : searchMap.entrySet()) {
                //如果key以spec_开始，则表示规格筛选查询
                String key = entry.getKey();
                if (key.startsWith("spec_")){
                    String value = entry.getValue();  //搜索条件
                    boolQuery.must(QueryBuilders.termQuery("specMap."+key.substring(5)+".keyword",value));
                }
            }

            //传入价格
            String price = searchMap.get("price");
            if (!StringUtils.isEmpty(price)){
                //price 0-500元 500-1000元 1000-1500元  1500-2000元 2000-3000元 3000元以上
                //去掉中文元和以上0-500 500- 1000 1000-1500 1500-2000 2000-3000 3000
                price = price.replace("元", "").replace("以上", "");
                //prices[]根据-分割 [0, 500] [500, 1000] ... [3000]
                String[] prices = price.split("-");
                if (prices!=null&&prices.length>0){
                    //x一定不为空，y有可能为null
                    //prices[O]!=null price>prices[0] price<=prices[1]
                    boolQuery.must(QueryBuilders.rangeQuery("price").gt(Integer.parseInt(prices[0])));
                    if (price.length()==2){
                        boolQuery.must(QueryBuilders.rangeQuery("price").lte(Integer.parseInt(prices[1])));
                    }
                }
            }

                //排序实现
                String sortField = searchMap.get("sortField"); //指定排序的域
                String sortRule = searchMap.get("sortRule"); // 指定排序的规则
                if(!StringUtils.isEmpty(sortField) && !StringUtils.isEmpty(sortRule)) {
                    nativeSearchQueryBuilder.withSort (
                            new FieldSortBuilder(sortField) //指定排序域
                                    .order(SortOrder.valueOf(sortRule))); //指定排序规则
                }

            }

        //传入分页
        Integer pageNum = coverterPage(searchMap);  //默认当前页
        Integer size = 5;  //默认查询的页面条数，一般由后台固定
        //第一个参数是当前页，默认从0开始，所以要减一
        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNum-1,size));

        //将boolQuery填充给nativeSearchQueryBuilder
        nativeSearchQueryBuilder.withQuery(boolQuery);

        return nativeSearchQueryBuilder;
    }

    /**
     * 接受前端传来的分页参数
     * @param searchMap
     * @return
     */
    public Integer coverterPage(Map<String,String> searchMap){
        if (searchMap!=null){
            try {
                String pageNum = searchMap.get("pageNum");
                //怕前端传个不能转换的，所以try,catch
                int parseInt = Integer.parseInt(pageNum);
                if (parseInt >= 1){
                    return parseInt;
                }
            } catch (NumberFormatException e) {
                //如果报错，值设为1
            }
        }
        return 1;
    }


    /**
     * 执行搜索,返回Map响应结果给我
     * 1)搜索条件封装对象
     * 2)搜索的结果集(集合数据)需要转换的类型
     * @param nativeSearchQueryBuilder
     * @return
     */
    private Map<String, Object> searchList(NativeSearchQueryBuilder nativeSearchQueryBuilder) {

        //高亮显示 可以添加多个域
        //高亮配置
        HighlightBuilder.Field name = new HighlightBuilder.Field("name"); //添加高亮域

        //前缀 <em color="red">
        name.preTags("<em color=\"red\">");
        //后缀</em>
        name.postTags("</em>");
        //碎片长度，高亮的前后偏移值(包含关键字的字段截取长度)，有默认值也可以手动控制
        name.fragmentSize(100);
        //添加高亮
        nativeSearchQueryBuilder.withHighlightFields(name);

        /**
         * page:当前搜索结果集的封装
         */
        AggregatedPage<SkuInfo> page = elasticsearchTemplate.queryForPage(
                nativeSearchQueryBuilder.build(), //搜索条件封装
                SkuInfo.class,  //数据集合要转换的类型的字节码
                new SearchResultMapper() {  //执行搜索后将结果封装到该对象中
                    //获取搜索搜索所有数据
                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                        //存储所有高亮数据
                        List<T> content = new ArrayList<>();
                        //如果没有结果返回为空
                        if (response.getHits() == null || response.getHits().getTotalHits() <= 0) {
                            return new AggregatedPageImpl<T>(content);
                        }
                        //执行查询， 获取所有数据->结果集[非高亮数据|高亮数据]
                        for (SearchHit searchHit : response.getHits()) {
                            //分析结果集数据，获取非高亮数据.获取的是JSON格式的数据
                            String sourceAsString = searchHit.getSourceAsString();
                            //转成skuInfo
                            SkuInfo skuInfo = JSON.parseObject(sourceAsString, SkuInfo.class);
                            //分析结果集数据，获取高亮数据->只有某个域的高亮数据

                            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                            HighlightField highlightField = highlightFields.get("name");

                            //有高亮则设置高亮的值
                            if (highlightField != null) {
                                StringBuffer stringBuffer = new StringBuffer();
                                //高亮数据读取出来
                                for (Text text : highlightField.getFragments()) {
                                    stringBuffer.append(text.string());
                                }
                                //将非高亮数据中指定域的数据替换成高亮数据
                                skuInfo.setName(stringBuffer.toString());
                            }
                            content.add((T)skuInfo);
                        }
                        /**
                         * 将数据返回
                         * 1)搜索的集合数据: (携带 高亮)List<T> content
                         * 2)分页对象信息: Pageable pageable (传过来了)
                         * 3)搜索记录的总条数: long total
                         */
                        return new AggregatedPageImpl<T>(content,pageable,response.getHits().getTotalHits());
                    }

                    @Override
                    public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                        return null;
                    }
                });





        //分析数据
        //分页参数-总记录数
        long totalElements = page.getTotalElements();

        //总页数
        int totalPages = page.getTotalPages();

        //数据结果集
        List<SkuInfo> content = page.getContent();

        //封装一个Map存储所有数据并返回
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rows",totalElements);
        map.put("total",content);
        map.put("totalPage",totalPages);
        return map;
    }


    /**
     * 将搜索到的规格参数分组合并，防止有重复的规格参数
     * @param nativeSearchQueryBuilder
     * @return
     */
    private HashMap<String, Set<String>> putAllSpec(NativeSearchQueryBuilder nativeSearchQueryBuilder) {
        /**
         *addAggregation:添加聚合（分组）
         * terms:取别名
         * field：分组的域
         * spec.keyword:表示随spec整个进行不分词的分组
         * size:查询的数据条数
         */
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuSpec").field("spec.keyword").size(10000));
        AggregatedPage<SkuInfo> aggregatedPage = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class);

        //获取分组数据 这里获取的是一个集合，因为可以根据多个域进行聚合
        Aggregations aggregations = aggregatedPage.getAggregations();
        //获取指定域的集合
        //将接受到的数据转换为字符串 是Aggregation的实现类
        /**
         * get ("skuSpec"):获取指定域的集合数 [{"电视音响效果”:”小影院”，”电视屏幕尺寸”:"20英寸”，”尺码”:”165"},
         * {"电视音响效果”:”立体声”，”电视屏幕尺寸”:”20英寸”，”尺码”:”165”}
         * }
         */
        StringTerms stringTerms = aggregations.get("skuSpec");

        //遍历将获取到的数据转换为集合
        List<String> spcList = new ArrayList<String>();
        for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
            String brandName = bucket.getKeyAsString(); //其中的一个规格名字
            spcList.add(brandName);
        }
        //规格汇总
        HashMap<String, Set<String>> allSpc = putAllSpc(spcList);


        return allSpc;
    }

    /**
     * 规格汇总
     * @param spcList
     * @return
     */
    private HashMap<String, Set<String>> putAllSpc(List<String> spcList) {
        //合并后的Map对象
        HashMap<String, Set<String>> allSpc = new HashMap<>();

        //1.循环specList
        for (String spc : spcList) {
            //2.将每个JSON字符串转成Map
            Map<String,String> spcMap = JSON.parseObject(spc, Map.class);
            //3.将每个Map对象合成成一个Map<String,Set<String>>
            //4.合并流程
            //4.1循环所有Map
            for (Map.Entry<String, String> entry : spcMap.entrySet()) {
                //4.2取出当前Map，并且获取对应的Key以及对应value
                String key = entry.getKey();  //规格名称
                String value = entry.getValue();  //规格值
                //4.3将当前循环的数据合并到一个Map<String, Set<String>>中
                Set<String> spcSet = allSpc.get(key);
                if (spcSet == null){
                    spcSet = new HashSet<>();
                }
                spcSet.add(value);
                allSpc.put(key,spcSet);
            }

        }
        return allSpc;
    }


    /**
     * 分组查询品牌集合
     * @param nativeSearchQueryBuilder
     * @return
     */
    private List<String> searchBrandList(NativeSearchQueryBuilder nativeSearchQueryBuilder) {
        /**
         *addAggregation:添加聚合（分组）
         * terms:取别名
         * field：分组的域
         */
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuBrand").field("brandName"));
        AggregatedPage<SkuInfo> aggregatedPage = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class);

        //获取分组数据 这里获取的是一个集合，因为可以根据多个域进行聚合
        Aggregations aggregations = aggregatedPage.getAggregations();
        //获取指定域的集合
        //将接受到的数据转换为字符串 是Aggregation的实现类
        StringTerms stringTerms = aggregations.get("skuBrand");

        //遍历将获取到的数据转换为集合
        List<String> brandList = new ArrayList<String>();
        for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
            String brandName = bucket.getKeyAsString(); //其中的一个分类名字
            brandList.add(brandName);
        }
        return brandList;
    }

    /**
     * 分组查询分类集合
     * @param nativeSearchQueryBuilder
     * @return
     */
    private List<String> searchCatogryList(NativeSearchQueryBuilder nativeSearchQueryBuilder) {
        /**
         *addAggregation:添加聚合（分组）
         * terms:取别名
         * field：分组的域
         */
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("skuCategory").field("categoryName"));
        AggregatedPage<SkuInfo> aggregatedPage = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class);

        //获取分组数据 这里获取的是一个集合，因为可以根据多个域进行聚合
        Aggregations aggregations = aggregatedPage.getAggregations();
        //获取指定域的集合
        //将接受到的数据转换为字符串 是Aggregation的实现类
        StringTerms stringTerms = aggregations.get("skuCategory");

        //遍历将获取到的数据转换为集合
        List<String> catogoryList = new ArrayList<String>();
        for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
            String skuName = bucket.getKeyAsString(); //其中的一个分类名字
            catogoryList.add(skuName);
        }
        return catogoryList;
    }


    /**
     * 导入数据到索引库中
     */
   /* @Override
    public void importData() {
        //Feign调用查询list<Sku>
        Result<List<Sku>> skuResult = skuFeign.findAll();
        //将list<SKu>转换为list<SkuInfo>
        List<SkuInfo> skuInfoList = JSON.parseArray(JSON.toJSONString(skuResult.getData()), SkuInfo.class);
        //将获得数据里的spec规格转换成Mapper结构，每个规格属性作为一个域
        for (SkuInfo skuInfo : skuInfoList) {
            Map<String,Object> specMap = JSON.parseObject(skuInfo.getSpec(), Map.class);
            //如果需要生成动态的域，只需要将该域存入到一个Map<String, Object>对象中即可，该Map<String, object>的key会生成一个域，域的名字为该Map的key
            //当前Map<String, Object>后面bject的值会O作为当前Sku对象该域(key)对应的值
            skuInfo.setSpecMap(specMap);
        }
        //调用Dao实现数据批量导入
        skuEsMapping.saveAll(skuInfoList);
    }*/

    /**
     * 导入数据到索引库中 增加商品状态查询
     */
    @Override
    public void importData() {
        Result<List<Sku>> listResult = skuFeign.findByStatus("1");

        List<Sku> data = listResult.getData();

        List<SkuInfo> skuInfos = JSON.parseArray(JSON.toJSONString(data), SkuInfo.class);

        for (SkuInfo skuInfo : skuInfos) {
            String spec = skuInfo.getSpec();
            Map map = JSON.parseObject(spec, Map.class);
            skuInfo.setSpecMap(map);
        }

        skuEsMapping.saveAll(skuInfos);
    }


}
